package com.tzbank.bigdata.service.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.alibaba.druid.util.StringUtils;
import com.tzbank.bigdata.dao.TradePeriodMapper;
import com.tzbank.bigdata.service.FtpTradePeriodService;
import com.tzbank.entity.bigdata.TradePeriod;
import lombok.extern.slf4j.Slf4j;

/**
 * @author wangbin 2018-07-03 从大数据ftp服务器读取数据文件入库,交易时段
 */

@Slf4j
@Service(value = "ftpTradePeriodService")
@RefreshScope
public class FtpTradePeriodServiceImpl implements FtpTradePeriodService {
	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private int type = 1;
	@Autowired
	private Environment environment;
	@Autowired
	private TradePeriodMapper tradePeriodMapper;

	@Override
	public boolean downFile() {
		List<TradePeriod> batList = new ArrayList<TradePeriod>();
		String host = environment.getProperty("host", String.class);
		int port = environment.getProperty("port", Integer.class).intValue();
		String username = environment.getProperty("username", String.class);
		String password = environment.getProperty("password", String.class);
		String path = environment.getProperty("path", String.class);
		log.info("开始到大数据平台取交易时段数据文件：" + "host=" + host + ";username=" + username + ";port=" + port + ";path=" + path);
		String dateTime = dateFormat.format(new Date());
		String date = dateTime.substring(0, 10).replaceAll("-", "");
		boolean success = false;
		FTPClient ftp = new FTPClient();
		try {
			// 连接并登陆ftp服务器
			ftp.connect(host, port);
			ftp.login(username, password);
			int replay = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(replay)) {
				log.info("登陆失败！");
				ftp.disconnect();
				return success;
			}
			ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
			if (path != null && path.length() > 0) {
				String newPath = path + date + "/";
				// 进入当天的数据文件目录
				ftp.changeWorkingDirectory(newPath);
				String fileName = "D60_MCJNL_TRADEPERIOD_" + date + "_001.dat";
				ftp.enterLocalActiveMode();
				InputStream ins = ftp.retrieveFileStream(fileName);
				if(ins == null) {
					log.info("ftp服务器没有文件或者文件为空，文件路径："+newPath+";文件名："+fileName);
					return success;
				}
				BufferedReader reader = new BufferedReader(new InputStreamReader(ins, "UTF-8"));
				String inLine = reader.readLine();
				while (inLine != null) {
					String beanStr = inLine + System.getProperty("line.separator");
					char split = (char) Integer.parseInt("1E", 16);
					String str = String.valueOf(split);
					if (beanStr.indexOf(str) > 0) {
						String[] beanStrs = beanStr.split(str);
						TradePeriod bat = new TradePeriod();
						bat.setMchannelid(beanStrs[0]);
						bat.setCustomerno(beanStrs[1]);
						bat.setCount12(beanStrs[2]);
						bat.setCount11(beanStrs[3]);
						bat.setCount10(beanStrs[4]);
						bat.setCount9(beanStrs[5]);
						bat.setCount8(beanStrs[6]);
						bat.setCount7(beanStrs[7]);
						bat.setCount6(beanStrs[8]);
						bat.setCount5(beanStrs[9]);
						bat.setCount4(beanStrs[10]);
						bat.setCount3(beanStrs[11]);
						bat.setCount2(beanStrs[12]);
						bat.setCount1(beanStrs[13].replace("\r\n", ""));
						bat.setCreateDate(dateTime);
						bat.setUpdateDate(dateTime);
						bat = this.doSort(bat);
						log.info("beanStrs[0]=" + beanStrs[0] + "beanStrs[1]=" + beanStrs[1] + "beanStrs[2]="
								+ beanStrs[2] + "beanStrs[3]=" + beanStrs[3]);
						batList.add(bat);
						// 批量入库操作，20条数据一批次
						if (batList.size() == 20) {
							this.batchInsert(batList);
							batList.clear();
						}
					}
					inLine = reader.readLine();
				}
				// 当最后一批次不够20条数据时，执行此入库操作
				if (batList != null && batList.size() < 20) {
					this.batchInsert(batList);
				}
				// 还原type值，下个跑批任务执行时，根据这个值先删除表数据再插入
				type = 1;
				reader.close();
				if (ins != null) {
					ins.close();
					// ftp.completePendingCommand();
				}
				ftp.logout();
				success = true;
				log.info("读取数据文件结束！");
			}
		} catch (Exception e) {
			log.info("从ftp读取数据文件失败", e);
			return success;
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException e) {
					log.info("关闭ftp连接失败", e);
				}
			}
		}
		return success;
	}

	/**
	 * 批量插入，每个批次开始时，先清空表数据，再插入
	 * 
	 * @param list
	 */
	@Transactional
	private void batchInsert(List<TradePeriod> list) throws Exception{
		if (type == 1) {
			this.tradePeriodMapper.deleteTradePeriod();
			type = 2;
		}
		this.tradePeriodMapper.insertTradePeriod(list);
	}

	/**
	 * 对十二个时段进行排序，并分出高频时段、中频时段和低频时段,排序后前两个为高频时段，第三第四个为中频时段，其余为低频时段
	 * 
	 * @param bat
	 * @return
	 */
	private TradePeriod doSort(TradePeriod bat) throws Exception{
		int count12 = 0;
		int count11 = 0;
		int count10 = 0;
		int count9 = 0;
		int count8 = 0;
		int count7 = 0;
		int count6 = 0;
		int count5 = 0;
		int count4 = 0;
		int count3 = 0;
		int count2 = 0;
		int count1 = 0;
		if (bat.getCount12() != null && !StringUtils.isEmpty(bat.getCount12())) {
			count12 = Integer.parseInt(bat.getCount12());
		}
		if (bat.getCount11() != null && !StringUtils.isEmpty(bat.getCount11())) {
			count11 = Integer.parseInt(bat.getCount11());
		}
		if (bat.getCount10() != null && !StringUtils.isEmpty(bat.getCount10())) {
			count10 = Integer.parseInt(bat.getCount10());
		}
		if (bat.getCount9() != null && !StringUtils.isEmpty(bat.getCount9())) {
			count9 = Integer.parseInt(bat.getCount9());
		}
		if (bat.getCount8() != null && !StringUtils.isEmpty(bat.getCount8())) {
			count8 = Integer.parseInt(bat.getCount8());
		}
		if (bat.getCount7() != null && !StringUtils.isEmpty(bat.getCount7())) {
			count7 = Integer.parseInt(bat.getCount7());
		}
		if (bat.getCount6() != null && !StringUtils.isEmpty(bat.getCount6())) {
			count6 = Integer.parseInt(bat.getCount6());
		}
		if (bat.getCount5() != null && !StringUtils.isEmpty(bat.getCount5())) {
			count5 = Integer.parseInt(bat.getCount5());
		}
		if (bat.getCount4() != null && !StringUtils.isEmpty(bat.getCount4())) {
			count4 = Integer.parseInt(bat.getCount4());
		}
		if (bat.getCount3() != null && !StringUtils.isEmpty(bat.getCount3())) {
			count3 = Integer.parseInt(bat.getCount3());
		}
		if (bat.getCount2() != null && !StringUtils.isEmpty(bat.getCount2())) {
			count2 = Integer.parseInt(bat.getCount2());
		}
		if (bat.getCount1() != null && !StringUtils.isEmpty(bat.getCount1())) {
			count1 = Integer.parseInt(bat.getCount1());
		}
		int[] count = { count1, count2, count3, count4, count5, count6, count7, count8, count9, count10, count11,
				count12 };
		int[] arr = { count12, count11, count10, count9, count8, count7, count6, count5, count4, count3, count2,
				count1 };
		// 冒泡排序
		for (int i = 0; i < arr.length - 1; i++) {
			for (int j = 0; j < arr.length - 1 - i; j++) {
				if (arr[j] < arr[j + 1]) {
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
		// 高频时段
		String highTime = "";
		// 中频时段
		String middleTime = "";
		for (int i = 0; i < count.length; i++) {
			if (arr[0] == count[i]) {
				highTime += "count" + String.valueOf(i + 1) + "|";
				if (arr[0] != 0) {
					count[i] = -arr[0];
				} else {
					count[i] = -1;
				}
				break;
			}
		}
		for (int i = 0; i < count.length; i++) {
			if (arr[1] == count[i]) {
				highTime += "count" + String.valueOf(i + 1) + "|";
				if (arr[1] != 0) {
					count[i] = -arr[1];
				} else {
					count[i] = -1;
				}
				break;
			}
		}
		for (int i = 0; i < count.length; i++) {
			if (arr[2] == count[i]) {
				middleTime += "count" + String.valueOf(i + 1) + "|";
				if (arr[2] != 0) {
					count[i] = -arr[2];
				} else {
					count[i] = -1;
				}
				break;
			}
		}
		for (int i = 0; i < count.length; i++) {
			if (arr[3] == count[i]) {
				middleTime += "count" + String.valueOf(i + 1) + "|";
				if (arr[3] != 0) {
					count[i] = -arr[3];
				} else {
					count[i] = -1;
				}
				break;
			}
		}
		bat.setHighTime(highTime);
		bat.setMiddleTime(middleTime);
		return bat;
	}
}
